//
//  ObjectTest.m
//  RBIOSBase
//
//  Created by ren on 13/09/2017.
//  Copyright © 2017 bryan. All rights reserved.
//

#import "ObjectTest.h"
#import <objc/message.h>
#import "ForwardObject.h"

@implementation ObjectTest

/**
 在实例化对象之前调用
 load 的加载方式是在main函数之前，只要在compile sources中，就会被加载，先加载父类中load，然后子类，然后才是分类。在整个App生命周期只加载一次。
 load被单独调用，如果子类直接调用，而子类中没有load方法，不会调用父类的load方法，不用显示调用父类中的load方法
 load中可以加载objc的method swizzle
 线程安全，内部都加了锁。不能再加锁
 */
+ (void)load
{
	NSLog(@"super class load----");
}


/**
 
 在实例化对象之前调用
 initialize 的加载是在main函数之后的，同时是在new或alloc调用时才会调用initialize方法，initialize方法是懒加载的，在整个App生命周期中只加载一次。
 initialize被单独调用，如果子类直接调用，而子类中没有initialize方法，会调用父类的initialize方法，不用显示调用父类中的initialize方法
 initialize方法中可以初始化静态变量，全局变量等
 线程安全，内部都加了锁。不能再加锁
 */
+ (void)initialize
{
	NSLog(@"super class initialize----%@", [self class]);
}

- (void)printDescription
{
	NSLog(@"%@", [self description]);
}

+ (void)printDesc
{
	NSLog(@"printDesc----->123123");
}

- (void)overrideVirtualMethod
{
	[self doesNotRecognizeSelector:_cmd];
}

//+ (BOOL)resolveInstanceMethod:(SEL)sel
//{
//	NSString *methodName = NSStringFromSelector(sel);
////	if ([methodName isEqualToString:@"testUnrecognizedSelector"]) {
////		IMP imp = [ObjectTest methodForSelector:@selector(printDesc)];
////		class_addMethod([self class], sel, imp, "v@:");
////		return YES;
////	}
//	return [super resolveInstanceMethod:sel];
//}
//
//+ (BOOL)resolveClassMethod:(SEL)sel
//{
////    Class cls = object_getClass(self);//元类对象，返回对象的isa
////    Class cls1 = [self class];//调用+(Class)class; 返回自身 如果调用-(Class)class;返回对象的isa
////    NSLog(@"%p--->cls--->%p,cls1---->%p",self, cls, cls1);
////    NSString *methodName = NSStringFromSelector(sel);
////    if ([methodName isEqualToString:@"testClassMethod"]) {
////        IMP imp = [ObjectTest methodForSelector:@selector(printDesc)];
////        class_addMethod(object_getClass(self), sel, imp, "v@:");//因为类方法在元类中
////        return YES;
////    }
//    return [super resolveClassMethod:sel];
//}
//
////如果resolveClassMethod和resolveInstanceMethod都解决不了，会跳转到这里
//- (id)forwardingTargetForSelector:(SEL)aSelector
//{
//    NSString *selectorStr = NSStringFromSelector(aSelector);
////    if ([selectorStr isEqualToString:@"testUnrecognizedSelector"]) {
////        ForwardObject *forwardObject = [ForwardObject new];
////        return forwardObject;//
////    }
//    return [super forwardingTargetForSelector:aSelector];
//}

- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
{
    NSMethodSignature *signature = [super methodSignatureForSelector:aSelector];
    if (!signature) {
        signature = [ForwardObject methodSignatureForSelector:@selector(testClassMethod)];
    }
    return signature;
}

+ (NSMethodSignature *)instanceMethodSignatureForSelector:(SEL)aSelector
{
    NSMethodSignature *signature = [super methodSignatureForSelector:aSelector];
    if (!signature) {
        signature = [ForwardObject methodSignatureForSelector:@selector(testClassMethod)];
    }
    return signature;
}

- (void)forwardInvocation:(NSInvocation *)anInvocation
{
    SEL selector = [anInvocation selector];
    if ([ForwardObject instancesRespondToSelector:selector]) {
        [anInvocation invokeWithTarget:[ForwardObject new]];
    }
    else {
        [super forwardInvocation:anInvocation];
    }
}

@end
